package com.fl.util.compress;

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import com.fl.util.FileUtil;


public abstract class AbstractFileCompressor implements FileCompressor {

    protected int             buffSize;

    /**
     * 文件前缀和后缀分隔符
     * */
    private static final char EXTENSION_SEPARATOR = '.';

    /**
     * java.io.File.separatorChar在UINX环境下的取值<br>
     */
    private static final char UNIX_SEPARATOR      = '/';

    /**
     * java.io.File.separatorChar在WIN环境下的取值<br>
     */
    private static final char WINDOWS_SEPARATOR   = '\\';

    public AbstractFileCompressor() {
        buffSize = FileCompressor.DEFAULT_BUFF_SIZE;
    }

    /**
     * 根据文件全路径返回文件全名，无论路径是win格式还是unix格式的<br>
     * 
     * <pre>
     * a/b/c.txt --> c.txt
     * a.txt     --> a.txt
     * a/b/c     --> c
     * a/b/c/    --> ""
     * </pre>
     * 
     * 
     * 
     * @param filename
     *            文件全路径
     * @return 文件全名，null参数返回null，无文件名则返回空字符串
     */
    protected String getName(String filename) {
        if (filename == null) {
            return null;
        }
        int index = indexOfLastSeparator(filename);
        return filename.substring(index + 1);
    }

    /**
     * 返回最后一个文件路径分隔符的位置,兼容win和unix的路径<br>
     * 
     * @param filename
     *            文件全路径, null 则返回 -1
     * @return 最后一个文件分隔符字符的位置, 无文件分隔符则返回-1
     */
    protected int indexOfLastSeparator(String filename) {
        if (filename == null) {
            return -1;
        }
        int lastUnixPos = filename.lastIndexOf(UNIX_SEPARATOR);
        int lastWindowsPos = filename.lastIndexOf(WINDOWS_SEPARATOR);
        return Math.max(lastUnixPos, lastWindowsPos);
    }

    /**
     * 根据文件全路径名返回文件前缀名(文件名中.前面部分)<br>
     * 
     * <pre>
     * a/b/c.txt --> c
     * a.txt     --> a
     * a/b/c     --> c
     * a/b/c/    --> ""
     * </pre>
     * 
     * @param filename
     *            文件全路径, null 则返回 null
     * @return 文件前缀名(文件名中.前面部分),路径中无文件名则返回空字符串
     */
    protected String getBaseName(String filename) {
        return removeExtension(getName(filename));
    }

    /**
     * 将文件全路径中文件后缀名去掉<br>
     * 
     * <pre>
     * foo.txt    --> foo
     * a\b\c.jpg  --> a\b\c
     * a\b\c      --> a\b\c
     * a.b\c      --> a.b\c
     * </pre>
     * 
     * @param filename
     *            文件全路径, null 则返回 null
     * @return 去除文件后缀名（包括.符号）的文件路径
     */
    protected String removeExtension(String filename) {
        if (filename == null) {
            return null;
        }
        int index = indexOfExtension(filename);
        if (index == -1) {
            return filename;
        } else {
            return filename.substring(0, index);
        }
    }

    /**
     * 返回文件名分隔符(.)的位置<br>
     * 
     * @param filename
     *            文件全路径, null 则返回 -1
     * @return 文件名分隔符(.)的位置，无则返回-1
     */
    protected int indexOfExtension(String filename) {
        if (filename == null) {
            return -1;
        }
        int extensionPos = filename.lastIndexOf(EXTENSION_SEPARATOR);
        int lastSeparator = indexOfLastSeparator(filename);
        return lastSeparator > extensionPos ? -1 : extensionPos;
    }

    /**
     * 
     *  输入输出流复制<br>
     * 调用FileUtil中的方法
     * 
     * @see com.unionpay.common.util.FileUtil#copyBytes(InputStream, OutputStream, int)
     * 
     * @param in  - 输入流
     * @param out - 输出流
     * @throws IOException 
     *  抛出异常
     */
    protected void copyStreams(InputStream in, OutputStream out) throws IOException {

        FileUtil.copyBytes(in, out, buffSize);
    }

    /**
     * 关闭输入输出流，吃掉所有异常 <br>
     * */
    protected void closeStreams(Closeable... closeables) {
        for (Closeable c : closeables) {
            if (c != null) {
                try {
                    c.close();
                } catch (IOException e) {
                    // 忽略所有IO异常
                    // if (log != null && log.isDebugEnabled()) {
                    // log.debug("Exception in closing " + c, e);
                    // }
                }
            }
        }
    }

}
